import type { ApiResponse } from '@/types'
import { API_CONFIG, HTTP_STATUS, BIZ_CODE } from './config'
import { useUserStore } from '@/store/user'

/**
 * HTTP请求工具类
 */
class HttpRequest {
  private baseURL: string
  private timeout: number

  constructor() {
    this.baseURL = API_CONFIG.BASE_URL
    this.timeout = API_CONFIG.TIMEOUT
  }

  /**
   * 请求拦截器
   */
  private interceptRequest(config: UniApp.RequestOptions) {
    const userStore = useUserStore()
    const token = userStore.token

    // 添加token
    if (token) {
      config.header = {
        ...config.header,
        'Authorization': `Bearer ${token}`
      }
    }

    // 添加通用请求头
    config.header = {
      ...config.header,
      'Content-Type': 'application/json'
    }

    return config
  }

  /**
   * 响应拦截器
   */
  private interceptResponse(response: UniApp.RequestSuccessCallbackResult): Promise<any> {
    const { statusCode, data } = response

    // HTTP状态码处理
    if (statusCode !== HTTP_STATUS.SUCCESS) {
      this.handleHttpError(statusCode)
      return Promise.reject(new Error(`HTTP Error: ${statusCode}`))
    }

    const result = data as ApiResponse

    // 业务状态码处理
    if (result.code !== BIZ_CODE.SUCCESS) {
      this.handleBizError(result)
      return Promise.reject(new Error(result.message || '请求失败'))
    }

    return Promise.resolve(result.data)
  }

  /**
   * 处理HTTP错误
   */
  private handleHttpError(statusCode: number) {
    const messages: Record<number, string> = {
      [HTTP_STATUS.BAD_REQUEST]: '请求参数错误',
      [HTTP_STATUS.UNAUTHORIZED]: '未授权，请登录',
      [HTTP_STATUS.FORBIDDEN]: '权限不足',
      [HTTP_STATUS.NOT_FOUND]: '请求的资源不存在',
      [HTTP_STATUS.TOO_MANY_REQUESTS]: '请求过于频繁，请稍后再试',
      [HTTP_STATUS.SERVER_ERROR]: '服务器错误，请稍后再试'
    }

    const message = messages[statusCode] || '网络请求失败'

    uni.showToast({
      title: message,
      icon: 'none',
      duration: 2000
    })

    // 401跳转到登录页
    if (statusCode === HTTP_STATUS.UNAUTHORIZED) {
      const userStore = useUserStore()
      userStore.logout()
      uni.reLaunch({ url: '/pages/index/index' })
    }
  }

  /**
   * 处理业务错误
   */
  private handleBizError(result: ApiResponse) {
    const { code, message } = result

    // Token过期，刷新token或重新登录
    if (code === BIZ_CODE.TOKEN_EXPIRED) {
      const userStore = useUserStore()
      userStore.logout()
      uni.showToast({ title: '登录已过期，请重新登录', icon: 'none' })
      uni.reLaunch({ url: '/pages/index/index' })
      return
    }

    // 显示错误信息
    if (message) {
      uni.showToast({
        title: message,
        icon: 'none',
        duration: 2000
      })
    }
  }

  /**
   * 发起请求
   */
  public request<T = any>(options: UniApp.RequestOptions): Promise<T> {
    return new Promise((resolve, reject) => {
      // 添加baseURL
      if (!options.url.startsWith('http')) {
        options.url = this.baseURL + options.url
      }

      // 请求拦截
      const config = this.interceptRequest(options)

      // 设置超时
      config.timeout = this.timeout

      uni.request({
        ...config,
        success: (res) => {
          this.interceptResponse(res)
            .then(data => resolve(data))
            .catch(err => reject(err))
        },
        fail: (err) => {
          console.error('请求失败:', err)
          uni.showToast({
            title: '网络连接失败',
            icon: 'none'
          })
          reject(err)
        }
      })
    })
  }

  /**
   * GET请求
   */
  public get<T = any>(url: string, params?: Record<string, any>): Promise<T> {
    return this.request<T>({
      url,
      method: 'GET',
      data: params
    })
  }

  /**
   * POST请求
   */
  public post<T = any>(url: string, data?: Record<string, any>): Promise<T> {
    return this.request<T>({
      url,
      method: 'POST',
      data
    })
  }

  /**
   * PUT请求
   */
  public put<T = any>(url: string, data?: Record<string, any>): Promise<T> {
    return this.request<T>({
      url,
      method: 'PUT',
      data
    })
  }

  /**
   * DELETE请求
   */
  public delete<T = any>(url: string, params?: Record<string, any>): Promise<T> {
    return this.request<T>({
      url,
      method: 'DELETE',
      data: params
    })
  }

  /**
   * 上传文件
   */
  public upload(filePath: string, name: string = 'file', formData?: Record<string, any>): Promise<any> {
    return new Promise((resolve, reject) => {
      const userStore = useUserStore()
      const token = userStore.token

      uni.uploadFile({
        url: this.baseURL + API_CONFIG.UPLOAD_URL,
        filePath,
        name,
        formData,
        header: {
          'Authorization': `Bearer ${token}`
        },
        success: (res) => {
          if (res.statusCode === HTTP_STATUS.SUCCESS) {
            const data = JSON.parse(res.data) as ApiResponse
            if (data.code === BIZ_CODE.SUCCESS) {
              resolve(data.data)
            } else {
              reject(new Error(data.message))
            }
          } else {
            reject(new Error('上传失败'))
          }
        },
        fail: (err) => {
          console.error('上传失败:', err)
          reject(err)
        }
      })
    })
  }
}

// 导出实例
export const http = new HttpRequest()

// 导出默认实例
export default http
